-- /run print((select(4, GetBuildInfo()))) 获取版本号，放到toc文件中
print("熊猫人之谜猎人技能提示工具")

---------------------- [1] 常量定义 ----------------------
-- 预定义纹理ID（熊猫人之谜版本）
local TEXTURE_EAGLE = 136076   -- 雄鹰守护
local TEXTURE_SERPENT = 132204 -- 毒蛇钉刺

-- 法术ID
local SPELL_SERPENT_STING = 1978    -- 毒蛇钉刺施放ID
local SPELL_ARCANE_SHOT_ID = 3044
local SPELL_STEADY_SHOT_ID = 56641
local DEBUFF_SERPENT_STING = 118253 -- 毒蛇钉刺debuff ID
local BUFF_EAGLE = 13165            -- 雄鹰守护buff ID
local EXPLOSIVE_SHOT_SPELL_ID = 53301 -- 爆炸射击法术ID

-- 系统常量
local MAX_AURA_SCANS = 40  -- 最大光环扫描次数
local GCD_DURATION = 1.5   -- 公共冷却时间
local EXPLOSIVE_FOCUS_COST = 25  -- 爆炸射击集中值消耗
local ARCANE_FOCUS_COST = 50     -- 奥术射击集中值消耗
local SPELL_POWER_FOCUS = 2      -- 集中值类型ID
local STEADY_SHOT_FOCUS_GAIN = 14  -- 稳固射击获得的集中值
local EXPLOSIVE_COOLDOWN_THRESHOLD = 3  -- 爆炸射击冷却完成阈值（秒）

-- 位置保存变量名
local POSITION_SAVE_VAR = "HunterSkillReminderPosition"

---------------------- [2] 位置保存与加载函数 ----------------------
-- 保存位置函数
local function SavePosition()
    local point, relativeTo, relativePoint, x, y = skillTipFrame:GetPoint()
    HunterSkillReminderPosition = {
        point = point,
        relativeTo = relativeTo:GetName(),
        relativePoint = relativePoint,
        x = x,
        y = y
    }
end

-- 加载位置函数
local function LoadPosition()
    if HunterSkillReminderPosition then
        skillTipFrame:ClearAllPoints()
        skillTipFrame:SetPoint(
                HunterSkillReminderPosition.point,
                _G[HunterSkillReminderPosition.relativeTo],
                HunterSkillReminderPosition.relativePoint,
                HunterSkillReminderPosition.x,
                HunterSkillReminderPosition.y
        )
        return true
    end
    return false
end

-- 位置初始化函数
local function InitializePosition()
    if not LoadPosition() then
        -- 如果没有保存的位置，使用默认位置
        skillTipFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -130)
    end
end

---------------------- [3] 主技能提示框架 ----------------------
local skillTipFrame = CreateFrame("Frame", nil, UIParent)
skillTipFrame:SetSize(124, 40)

-- 创建图标函数
local function CreateSkillIcon(parent, texture, size, point, relativeTo, relativePoint, x, y)
    local icon = parent:CreateTexture(nil, "OVERLAY")
    icon:SetSize(size, size)
    icon:SetPoint(point, relativeTo, relativePoint, x, y)
    icon:SetTexture(texture)
    return icon
end

-- 创建雄鹰守护图标
local eagleIcon = CreateSkillIcon(skillTipFrame, TEXTURE_EAGLE, 40, "LEFT", skillTipFrame, "LEFT", 0, 0)
eagleIcon:Hide()

-- 创建爆炸射击图标
local bzsjIcon1 = CreateSkillIcon(skillTipFrame, 236178, 40, "LEFT", eagleIcon, "RIGHT", 0, 0)
bzsjIcon1:Hide()

-- 创建奥术射击图标
local arcaneIcon = CreateSkillIcon(skillTipFrame, 132218, 40, "LEFT", eagleIcon, "RIGHT", 0, 0)
arcaneIcon:Hide()

-- 创建稳固射击图标
local wgsjIcon1 = CreateSkillIcon(skillTipFrame, 132213, 40, "LEFT", eagleIcon, "RIGHT", 0, 0)
wgsjIcon1:Hide()

-- 创建毒蛇钉刺图标
local serpentIcon1 = CreateSkillIcon(skillTipFrame, TEXTURE_SERPENT, 40, "LEFT", eagleIcon, "RIGHT", 0, 0)
serpentIcon1:Show()

-- 创建右侧图标
local dcsjIcon = CreateSkillIcon(skillTipFrame, 132330, 40, "LEFT", serpentIcon1, "RIGHT", 0, 0)
dcsjIcon:Show()

local wgsjIcon2 = CreateSkillIcon(skillTipFrame, 132213, 40, "LEFT", serpentIcon1, "RIGHT", 0, 0)
wgsjIcon2:Hide()

-- AOE时的爆炸射击
local bzsjIcon2 = CreateSkillIcon(skillTipFrame, 236178, 40, "LEFT", serpentIcon1, "RIGHT", 0, 0)
bzsjIcon2:Hide()

---------------------- [4] 多功能控制面板 ----------------------
-- 创建控制面板（200x200）
local controlPanel = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
controlPanel:SetSize(200, 200)
controlPanel:SetPoint("RIGHT", UIParent, "RIGHT", -20, 0) -- 右侧20像素位置

-- 设置面板背景和边框
controlPanel:SetBackdrop({
    bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
    edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
    tile = true,
    tileSize = 32,
    edgeSize = 32,
    insets = { left = 11, right = 11, top = 11, bottom = 9 }
})
controlPanel:SetBackdropColor(0, 0, 0, 0.8)
controlPanel:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)

-- 面板标题
local titleText = controlPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
titleText:SetPoint("TOP", controlPanel, "TOP", 0, -15)
titleText:SetText("猎人技能管理")
titleText:SetTextColor(1, 0.8, 0) -- 金色标题

---------------------- [5] 重置位置功能 ----------------------
-- 位置重置函数
local function ResetPosition()
    skillTipFrame:ClearAllPoints()
    skillTipFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -130)
    print("技能图标位置已重置！")
    SavePosition()  -- 保存位置
end

-- 在控制面板中添加重置按钮
local resetButton = CreateFrame("Button", nil, controlPanel, "UIPanelButtonTemplate")
resetButton:SetSize(120, 25)
resetButton:SetPoint("TOP", titleText, "BOTTOM", 0, -20)
resetButton:SetText("重置图标位置")
resetButton:SetScript("OnClick", ResetPosition)

-- 添加重置按钮提示
local resetTip = controlPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
resetTip:SetPoint("TOP", resetButton, "BOTTOM", 0, -5)
resetTip:SetText("将技能图标恢复默认位置")
resetTip:SetTextColor(0.8, 0.8, 0.8)

---------------------- [6] 位置锁定功能 ----------------------
-- 创建锁定复选框
local lockCheck = CreateFrame("CheckButton", nil, controlPanel, "UICheckButtonTemplate")
lockCheck:SetSize(24, 24)
lockCheck:SetPoint("TOP", resetTip, "BOTTOM", 0, -20)

-- 设置复选框文本
lockCheck.text = lockCheck:CreateFontString(nil, "OVERLAY", "GameFontNormal")
lockCheck.text:SetPoint("LEFT", lockCheck, "RIGHT", 5, 0)
lockCheck.text:SetText("锁定位置")
lockCheck.text:SetTextColor(1, 1, 1)

-- 初始状态为锁定
lockCheck:SetChecked(true)

-- 锁定/解锁功能实现
local function UpdateLockState()
    local locked = lockCheck:GetChecked()
    skillTipFrame:EnableMouse(not locked) -- 锁定后禁用鼠标交互
    skillTipFrame:SetMovable(not locked)  -- 锁定后禁止移动
    print(locked and "图标已锁定" or "图标已解锁")
end

-- 初始设置锁定状态
UpdateLockState()

-- 绑定点击事件
lockCheck:SetScript("OnClick", UpdateLockState)

---------------------- [7] 拖动功能 ----------------------
-- 拖动支持（受锁定状态控制）
skillTipFrame:SetMovable(true)
skillTipFrame:RegisterForDrag("LeftButton")

-- 设置拖动脚本
skillTipFrame:SetScript("OnDragStart", function(self)
    if self:IsMovable() then
        self:StartMoving()
    end
end)

skillTipFrame:SetScript("OnDragStop", function(self)
    if self:IsMovable() then
        self:StopMovingOrSizing()
        SavePosition()  -- 保存位置
    end
end)

---------------------- [8] 光环检测辅助函数 ----------------------
local function FindBuff(spellId)
    for i = 1, MAX_AURA_SCANS do
        local _, _, _, _, _, _, _, _, _, buffSpellId = UnitBuff("player", i, "PLAYER")
        if not buffSpellId then break end
        if buffSpellId == spellId then
            return true
        end
    end
    return false
end

local function FindDebuff(spellId)
    for i = 1, MAX_AURA_SCANS do
        local _, _, _, _, _, expiration, _, _, _, debuffSpellId = UnitDebuff("target", i, "PLAYER")
        if not debuffSpellId then break end
        if debuffSpellId == spellId then
            return expiration > GetTime()  -- 返回是否有效
        end
    end
    return false
end

---------------------- [9] 毒蛇钉刺检测 ----------------------
local lockSerpentStingCheck = false;
local serpentCastTime = 0  -- 记录施放时间

skillTipFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
skillTipFrame:RegisterEvent("UNIT_SPELLCAST_STOP")
skillTipFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
skillTipFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
skillTipFrame:SetScript("OnEvent", function(self, event, ...)
    if event == "UNIT_SPELLCAST_SUCCEEDED" then
        local unit, _, spellID = ...
        if unit == "player" and spellID == SPELL_SERPENT_STING then
            lockSerpentStingCheck = true;
            serpentCastTime = GetTime()
        end
    elseif event == "UNIT_SPELLCAST_STOP" then
        local unit, _, spellID = ...
        if unit == "player" and spellID == SPELL_SERPENT_STING then
            lockSerpentStingCheck = false;
        end
    elseif event == "PLAYER_TARGET_CHANGED" then
        lockSerpentStingCheck = false
    elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
        local _, subEvent, _, sourceGUID, _, _, _, destGUID, _, _, _, spellID = CombatLogGetCurrentEventInfo()

        -- 检查是否是玩家施放的毒蛇钉刺未命中
        if sourceGUID == UnitGUID("player") and spellID == SPELL_SERPENT_STING then
            if subEvent == "SPELL_MISSED" or subEvent == "SPELL_DODGED" or subEvent == "SPELL_PARRYED" then
                lockSerpentStingCheck = false
            end
        end
    end
end)

---------------------- [10] 集中值预测函数 ----------------------
local function CalculateArcaneFocusRequirement()
    local currentFocus = UnitPower("player", Enum.PowerType.Focus)

    -- 检查是否正在施放稳固射击
    local _, _, _, _, _, _, _, castingSpellID = UnitCastingInfo("player")
    if not castingSpellID then
        _, _, _, _, _, _, castingSpellID = UnitChannelInfo("player")
    end

    if castingSpellID == SPELL_STEADY_SHOT_ID then
        return currentFocus + STEADY_SHOT_FOCUS_GAIN
    end

    return currentFocus
end

---------------------- [11] 主更新函数 ----------------------
-- 设置更新频率
local updateInterval = 0.2
local elapsed = 0

skillTipFrame:SetScript("OnUpdate", function(self, delta)
    elapsed = elapsed + delta
    if elapsed < updateInterval then return end
    elapsed = 0

    -- 超时检测：如果锁定状态超过3秒，自动重置
    if lockSerpentStingCheck and (GetTime() - serpentCastTime) > 3 then
        lockSerpentStingCheck = false
    end

    -- 战斗状态检测
    local inCombat = UnitAffectingCombat("player")
    local leanEagle = IsSpellKnown(BUFF_EAGLE)

    -- 雄鹰守护检测
    if inCombat and leanEagle then
        eagleIcon:SetShown(not FindBuff(BUFF_EAGLE))
    else
        eagleIcon:Hide()
    end

    --------------- 毒蛇钉刺检测 ---------------
    local leanSerpentSting = IsSpellKnown(SPELL_SERPENT_STING)
    local needSpellSerpent = false

    if leanSerpentSting then
        local hasSerpentDebuff = FindDebuff(DEBUFF_SERPENT_STING)
        if hasSerpentDebuff then
            lockSerpentStingCheck = false
        end
        needSpellSerpent = not hasSerpentDebuff and not lockSerpentStingCheck
    end

    serpentIcon1:SetShown(needSpellSerpent and leanSerpentSting and not lockSerpentStingCheck)
    --------------- 毒蛇钉刺检测结束 ---------------

    -- 获取当前集中值
    local currentFocus = UnitPower("player", Enum.PowerType.Focus)

    -- 爆炸射击检测
    local leanExplosiveShot = IsSpellKnown(EXPLOSIVE_SHOT_SPELL_ID)
    local explosiveAvailable = false
    local explosiveCooldownRemaining = 0  -- 爆炸射击剩余冷却时间

    if leanExplosiveShot then
        local start, duration, enabled = GetSpellCooldown(EXPLOSIVE_SHOT_SPELL_ID)
        if enabled ~= 0 then
            if duration == 0 or duration <= GCD_DURATION then
                explosiveAvailable = true
            else
                explosiveCooldownRemaining = start + duration - GetTime()
            end
        end

        explosiveAvailable = explosiveAvailable and (currentFocus >= EXPLOSIVE_FOCUS_COST)
    end

    bzsjIcon1:SetShown(explosiveAvailable and (not needSpellSerpent or lockSerpentStingCheck))
    bzsjIcon2:SetShown(explosiveAvailable and (not needSpellSerpent or lockSerpentStingCheck))

    -- 奥术射击检测
    local arcaneAvailable = false
    if IsSpellKnown(SPELL_ARCANE_SHOT_ID) then
        local predictedFocus = CalculateArcaneFocusRequirement()

        if explosiveCooldownRemaining > 0 and explosiveCooldownRemaining < EXPLOSIVE_COOLDOWN_THRESHOLD then
            arcaneAvailable = predictedFocus >= 60  -- 保留集中值给爆炸射击
        else
            arcaneAvailable = predictedFocus >= ARCANE_FOCUS_COST
        end
    end

    arcaneIcon:SetShown(not explosiveAvailable and not needSpellSerpent and arcaneAvailable)

    -- 稳固射击检测
    local showSteady = not explosiveAvailable and not needSpellSerpent and not arcaneAvailable
    wgsjIcon1:SetShown(showSteady and IsSpellKnown(SPELL_STEADY_SHOT_ID))

    -- 右侧图标显示
    local showFocusIndicator = currentFocus < 40
    wgsjIcon2:SetShown(showFocusIndicator)
    dcsjIcon:SetShown(not showFocusIndicator)
end)

---------------------- [12] 斜杠命令 ----------------------
-- 注册重置位置斜杠命令
SLASH_RESETPOSITION1 = "/rp" -- 主命令
SLASH_RESETPOSITION2 = "/resetpos" -- 备用命令
SlashCmdList["RESETPOSITION"] = ResetPosition

-- 注册锁定/解锁斜杠命令
SLASH_LOCKUI1 = "/lockui"
SlashCmdList["LOCKUI"] = function()
    lockCheck:SetChecked(not lockCheck:GetChecked())
    UpdateLockState()
end

-- 添加提示信息
print("控制命令:")
print("- /rp 或 /resetpos: 重置图标位置")
print("- /lockui: 切换锁定状态")
print("- 控制面板位于屏幕右侧")

---------------------- [13] 位置初始化 ----------------------
InitializePosition()